---
sidebar_position: 3
title: Proofs
---

import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"

# Semaphore proofs

Once a user joins a [Semaphore group](/glossary#group) with their [Semaphore identity](/glossary#identity), the user can send their anonymous [message](/glossary#message) with a zero-knowledge proof that proves the following:

- the user is a member of the group,
- the same user created the message and the proof.

A unique [nullifier](/glossary#nullifier) is also generated for each proof that can be used to check whether that proof has already been validated.

## Install package

In your code, use the [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/proof) package to generate and verify a proof.

<Tabs
  defaultValue="npm"
  groupId="package-managers"
  values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
  <TabItem value="npm">
    ```bash
    npm install @semaphore-protocol/proof
    ```
  </TabItem>

  <TabItem value="yarn">
    ```bash
    yarn add @semaphore-protocol/proof
    ```
  </TabItem>

  <TabItem value="pnpm">
    ```bash
    pnpm add @semaphore-protocol/proof
    ```
  </TabItem>
</Tabs>

:::info
Semaphore also provides `@semaphore-protocol/core`, which includes the functions of the following core packages: `@semaphore-protocol/identity`, `@semaphore-protocol/group`, `@semaphore-protocol/proof`.
:::

## Generate a proof

### 1. Create the identity

In order for a user to generate a proof, it is necessary to create a Semaphore identity. If you do not know how to
create an identity, see the previous [guide](/guides/identities) on identities.

### 2. Create the group

Before generating a proof you also need to create a Semaphore group containing the commitment of the Semaphore identity of the user who will generate the proof. If you do not know how to create a group, see the previous [guide](/guides/groups) on groups.

If your group is on-chain, you can use the [`@semaphore-protocol/data`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/data) library to fetch the group members and re-create the off-chain group. For example:

```ts
import { SemaphoreSubgraph } from "@semaphore-protocol/data"
import { Group } from "@semaphore-protocol/group"

const semaphoreSubgraph = new SemaphoreSubgraph("sepolia")

const { members } = await semaphoreSubgraph.getGroup("42", { members: true })

const group = new Group(members)
```

### 3. Choose the scope

Each proof requires a [scope](/glossary#scope), on which each user may only generate one valid proof. The scope, together with the user's private key, is used to generate the nullifier, which is the value you can actually use to check whether a proof with that scope has already been generated by that user. In a voting application where double-voting must be prevented, the scope could be the ballot id, or the Merkle root of the group.

### 4. Generate the anonymous message

Finally, you can generate the proof with the anonymous message using the `generateProof` function. For example:

```ts
import { generateProof } from "@semaphore-protocol/proof"

const scope = group.root
const message = 1

const proof = await generateProof(identity, group, message, scope)
```

## Verify a proof

To verify a proof, pass the proof you generated to the `verifyProof` function. For example:

```ts
import { verifyProof } from "@semaphore-protocol/proof"

await verifyProof(proof) // true or false.
```

If you want to validate a proof on-chain, you can use [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts) and the [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/Semaphore.sol) contract, as explained in the previous [guide](/guides/groups#install-package-1), and use the `validateProof` function. For example:

```solidity
function validateProof(ISemaphore.SemaphoreProof calldata proof) external {
    semaphore.validateProof(groupId, proof);
}
```
